package main

import (
	"bytes"
	"fmt"
	"log"
	"os"
	"os/exec"
	"time"

	"fish-scaner/admin"
	"fish-scaner/binary"

	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/net/ghttp"
	"github.com/gogf/gf/os/gcmd"
	"github.com/gogf/gf/os/gfile"
	"github.com/gogf/gf/os/gproc"
	"github.com/gogf/gf/os/gsession"
	"github.com/gogf/gf/util/gconv"
)

var WorkDir string
var Server *ghttp.Server

func help() {
	fmt.Println("This is help.")
}

func test() {
	fmt.Println("This is test.")
}

func main() {
	WorkDir = gcmd.GetOpt(`work-dir`, os.Getenv("HOME")+`/object/rzh/`)

	log.Println(os.Getenv("HOME") + `/object/rzh/`)
	// go initEnv()
	err := gfile.Mkdir(WorkDir + `tmp_files/zip_files/`)
	fmt.Println(WorkDir + `tmp_files/zip_files/`)
	if err != nil {
		log.Fatalln(err)
	}
	err = gfile.Mkdir(WorkDir + `tmp_files/`)
	if err != nil {
		log.Fatalln(err)
	} else {
		go initLibs()
	}
	// for key, val := range binary.Binary {
	// log.Println(key, `: `, val)
	// }
	// log.Println(binary.Binary[`test.json`].String())

	Server := g.Server()

	Server.EnableAdmin()

	// s.EnablePProf()
	Server.SetIndexFolder(true)
	Server.SetConfigWithMap(g.Map{
		// "SessionMaxAge":	time.Minute,
		"SessionStorage":	gsession.NewStorageRedis(g.Redis()),
		"AccessLogEnabled": true,
		"ErrorLogEnabled":	true,
		"PProfEnabled":		true,
		"LogPath":			"/tmp/var/log/ServerLog",
		// "SessionIdName":	"MySessionId",
		// "SessionPath":		"/tmp/MySessionStoragePath",
		"SessionMaxAge": 50 * time.Hour,
	})
	// s.SetServerRoot("/www/wwwroot/ws.seafishery.com")
	// ctr := new(Controller)

	// s.BindHandler("/api/ok", func(r *ghttp.Request) {
	// r.Response.WriteExit(`ok`)
	// })
	Server.BindHandler("/ws.html", func(r *ghttp.Request) {
		r.Response.WriteExit(binary.Binary[`ws.html`].String())
	})
	ctr := new(Controller)
	Server.BindObject("/api", ctr)

	// hash, err := admin.PasswordHash([]byte(`szsys`))
	// if err != nil {
	// glog.Error(err)
	// r.Exit()
	// }
	usersMap := gconv.Map(g.Map{`szsys`: `szsys`})
	// tst.Pl(usersMap)

	// hash, err := PasswordHash(pass)
	// if err != nil {
	// panic(err)
	// }
	// usersMap[user] = hash
	g.Redis().Do(`SET`, `users`, usersMap)
	g.Redis().Do(`SET`, `admin`, []byte(`szsys`))

	Server.Group("/auth", func(group *ghttp.RouterGroup) {
		group.Middleware(basicAuth)
		group.ALL("/wsml", func(r *ghttp.Request) {
			// r.Response.Writeln("list")
			r.Response.Write(binary.Binary[`ws.html`])
		})
	})

	Server.Group("/admin", func(group *ghttp.RouterGroup) {
		group.Middleware(adminAuth)
		// Server.BindObject("/api", ctr)
		group.ALL("/passwd", admin.Passwd)
		group.ALL("/auth", admin.Auth)
		// group.ALL("/passwd", func(r *ghttp.Request) {
		// r.Response.Writeln("list")

		// r.Response.Write(binary.Binary[`ws.html`])
		// })
	})
	// Server.Group("/auth", func(group *ghttp.RouterGroup) {
	// group.Middleware(basicAuth)
	// group.ALL("/wsml", func(r *ghttp.Request) {
	// r.Response.Writeln("list")
	// r.Response.Write(binary.Binary[`ws.html`])
	// })
	// })
	// s.BindHandler("/ws", func(r *ghttp.Request) {
	//	ws, err := r.WebSocket()
	//	if err != nil {
	//		glog.Error(err)
	//		r.Exit()
	//	}
	//	for {
	//		msgType, msg, err := ws.ReadMessage()
	//		if err != nil {
	//			return
	//		}
	//		if err = ws.WriteMessage(msgType, msg); err != nil {
	//			return
	//		}
	//	}
	// })
	// // SSLCertificateFile /www/server/panel/vhost/cert/ws.seafishery.com/fullchain.pem
	// // SSLCertificateKeyFile /www/server/panel/vhost/cert/ws.seafishery
	// // s.SetServerRoot(gfile.MainPkgPath())
	// // s.SetServerRoot("/www/wwwroot/ws.seafishery.com")
	Server.SetServerRoot(WorkDir + "tmp_files/")
	// s.EnableHTTPS("/www/server/panel/vhost/cert/ws.seafishery.com/fullchain.crt", "/www/server/panel/vhost/cert/ws.seafishery.com/privkey.key")
	Server.SetPort(10086)
	// runtime.GOMAXPROCS(8)
	// ch := make(chan bool, 1)
	// fileCount := 0

	// j, err := gjson.LoadJson(binary.Binary[`test.json`].String())
	// j, _ := gjson.LoadJson(binary.Binary[`test.json`].String())
	// if err != nil {
	// log.Println(`ioutil2`, err)
	// }
	// if p, e := gparser.LoadContent(binary.Binary[`test.json`].Bytes(), true); e != nil {
	// glog.Error(e)
	// } else {
	// jsonTest := p.GetMap(`fishes`)
	// err := p.GetMap(`fishes`)
	// if err != nil {
	// log.Println(`ioutil2`, err)
	// }
	// for key, val := range jsonTest {
	// fmt.Println(key, `: `, val)
	// }
	// }
	// time.Sleep(10e9)
	// parser, err := gcmd.Parse(g.MapStrBool{
	// "n,name":	true,
	// "v,version": true,
	// "a,arch":	true,
	// "o,os":		true,
	// "p,path":	true,
	// })
	// path := gcmd.GetOpt(`work-dir`, `/var/run/`)
	// fmt.Println(os.Getenv("HOME"))
	// for _, pkg := range os.Args[1:] {
	// pip(pkg)
	// }
	// gcmd.BindHandle("help", help)
	// gcmd.BindHandle("test", test)
	// gcmd.AutoRun()
	Server.Run()
}

// func initEnv() {
// }

func initLibs() {

	ch, fileCount := binary.Init(WorkDir)
	// binary.Init(os.Getenv("HOME") + `/backup`)
	// for i := 0; i < fileCount; i++ {
	// fmt.Println(i)
	// <-ch
	// }
	// var libNames map[string][]string
	// for _, fileName := range []string{`container.html`, `footer.html`, `header.html`, `layout.html`, `ws.html`} {
	// ch := make(chan bool)

	// fileCount := 0
	// for _, fileName := range fileNames {
	// go downloadLib(`template/`, fileName, ch)
	// idx++
	// }
	// for idx, fileName := range []string{`fishdb_ke.py`, `fundiving_ke.py`, `fishdb_shu.py`, `fundiving_shu.py`} {
	// go downloadLib(``, fileName, ch[idx])
	// go downloadLib(``, fileName, ch)
	// fileCount = idx
	// }

	// PythonRequireUpToDate = false
	log.Println(`检查python依赖......`)
	for _, version := range []string{`3`, ``} {
		installFail := false
		for _, pkg := range []string{`requests`, `bs4`, `eventlet`} {
			// fmt.Println(pkg, version)

			stdout, err := pip(version, pkg)
			if err != nil {
				if version == `` {
					log.Println(`python包下载失败: ` + pkg)
					log.Fatalln(err.Error())
					// return nil, err
				}
				installFail = true

			} else if pkg == `eventlet` && !installFail {
				// PythonRequireUpToDate = true
				log.Println(`python依赖 already up-to-date`)
				for i := 0; i < fileCount; i++ {

					<-ch // 等待写入任务完成

				}
				log.Println(`personal libs already up-to-date`)
				gproc.ShellExec(`sed -i 's/\t/	  /g' ` + WorkDir + `*.py`)
				return
			}
			log.Println(string(stdout))
			// return analysisCollectOutput(stdout)
			// }
		}
	}

}

func pip(pipVersion, pkg string) ([]byte, error) {
	// fmt.Println(`--------------------------installing`, pkg)

	cmd := exec.Command(`pip`+pipVersion, `install`, pkg)
	// log.Println(os.Args[1])
	// stdout, err := cmd.StdoutPipe()
	// if err != nil {
	// log.Println(err)
	// }
	// stdErr, err := cmd.StderrPipe()
	// if err != nil {
	// log.Println(err)
	// }
	// content, ioErr := ioutil.ReadAll(stdErr)
	// var content io.ReadCloser
	// _, ioErr := bytes.NewBuffer(content).WriteTo(stdErr)
	// io
	// if ioErr != nil {
	// log.Println(`ioutil2`, ioErr)
	// }
	// buf := new(ioutil.ReadDir)
	// NewWriter(cmd.Stdout)
	// cmd.Stdout = buf
	// // err = cmd.Start()
	// // cmd.Wait
	// // log.Println(`hasRun`)
	// // content, ioErr := ioutil.ReadAll(stdout)
	// // if ioErr != nil {
	// // log.Println(`ioutil1`, ioErr)
	// // }
	// // fmt.Println(`stdout`, string(content))
	// content, ioErr := ioutil.ReadAll(stdErr)
	// if ioErr != nil {
	//	log.Println(`ioutil2`, ioErr)
	// }
	// if cmd.ProcessState.ExitCode() != 0 {
	// fmt.Println(`stderr$$$$$$$$$$$$$$$$$$$$$$`, cmd.ProcessState.ExitCode(), string(content))

	// }
	// err = cmd.Start()
	// err = cmd.Run()
	var stdout, stderr bytes.Buffer
	cmd.Stdout = &stdout
	cmd.Stderr = &stderr
	err := cmd.Run()
	// log.Println(`@#*(^&**%$$%^#%#%*&(((&%^&*$&`, cmd.ProcessState.Success())
	// if !cmd.ProcessState.Success() {
	// ioutil.(cmd.Stdout)
	// content, ioErr := ioutil.ReadAll(stdErr)
	fmt.Println(string(stdout.Bytes()))
	fmt.Println(string(stderr.Bytes()))
	// buf.Flush()
	// log.Fatal(`$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$4`, string(*buf), `$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$4`)
	// }
	if err != nil {
		return stdout.Bytes(), err
		// log.Fatal(`$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$4`, err)
	}
	return stdout.Bytes(), nil
}
